package com.zyf.concurrency.chapter15;

import com.zyf.concurrency.annotations.GuardedBy;
import com.zyf.concurrency.annotations.ThreadSafe;

/**
 * 模拟CAS操作
 * SimulatedCAS说明了CAS语义(而不是实现或性能)。
 * create by yifeng
 */
@ThreadSafe
public class SimulatedCAS {
    @GuardedBy("this")
    private int value;
    public synchronized int get() {
        return value;
    }

    /**
     * 这个方法是说明了CAS的语义
     * 很重要的一点是：CAS需要知道 {@code value} 当前的最新值是不是客户拿到的值，即{@code expectedValue}
     * @param expectedValue 预期值
     * @param newValue cas成功，则将{@code this.value}设置成该值
     * @return
     */
    public synchronized int compareAndSwap(int expectedValue, int newValue) {
        // 解释一下吧，个人理解， 拿到当前最新的值，该值有可能被其他线程修改了
        int oldValue = value;
        // 如果value等于预期值（expectedValue）,则说明是最新值，cas成功
        if (oldValue == expectedValue)
            value = newValue;
        // 如果cas成功，则说明预期值是最新值，没有被其他线程修改
        // 如果cas失败，则说明value已被其他线程修改，这里将会返回value的最新值
        return oldValue;
    }

    /**
     * 比较并设置语义
     * @param expectedValue 预期值
     * @param newValue cas成功，则将{@code this.value}设置成该值
     * @return 如果预期值等于当前value值则返回 {@code true}，即cas成功,
     *          否则则返回 {@code false}，即cas失败
     */
    public synchronized boolean compareAndSet(int expectedValue, int newValue) {
        return (expectedValue == compareAndSwap(expectedValue, newValue));
    }
}
